﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TestApp.Domains
{
    public class Folder : Label
    {
        Subscription[] children;
        public IEnumerable<Subscription> Children
        {
            get
            {
                if (children == null)
                {
                    List<Subscription> subscriptions = new List<Subscription>();
                    List<FolderSubscriptionRel> rels = new List<FolderSubscriptionRel>();

                    var q = from r in rels
                            join s in subscriptions
                            on r.SubscriptionId equals s.Id
                            where r.FolderId == Id
                            select s;

                    children = q.ToArray();
                }

                return children;
            }
        }
    }

    public class Subscription : Label
    {
        Folder[] parents;
        public IEnumerable<Folder> Parents
        {
            get
            {
                if (parents == null)
                {
                    List<Folder> folders = new List<Folder>();
                    List<FolderSubscriptionRel> rels = new List<FolderSubscriptionRel>();

                    var q = from r in rels
                            join f in folders
                            on r.FolderId equals f.Id
                            where r.SubscriptionId == Id
                            select f;

                    parents = q.ToArray();
                }

                return parents;
            }
        }
    }

    public abstract class Label
    {
        public string Name { get; set; }

        public string Id { get; set; }

        public int Unread { get; set; }
    }

    public struct FolderSubscriptionRel : IEquatable<FolderSubscriptionRel>
    {
        public FolderSubscriptionRel(Folder folder, Subscription subscription)
            : this()
        {
            this.FolderId = folder.Id;
            this.SubscriptionId = subscription.Id;
        }

        public string FolderId { get; set; }

        public string SubscriptionId { get; set; }

        public override bool Equals(object obj)
        {
            return Equals((FolderSubscriptionRel)obj);
        }

        public override int GetHashCode()
        {
            return (this.FolderId + this.SubscriptionId).GetHashCode();
        }

        public bool Equals(FolderSubscriptionRel other)
        {
            return this.FolderId == other.FolderId && this.SubscriptionId == other.SubscriptionId;
        }

        public static bool operator ==(FolderSubscriptionRel r1, FolderSubscriptionRel r2)
        {
            return r1.Equals(r2);
        }
        public static bool operator !=(FolderSubscriptionRel r1, FolderSubscriptionRel r2)
        {
            return !r1.Equals(r2);
        }
    }
}
